#include "mongoc_const.h"
#include "mongoc_data.h"
#include <stdio.h>

int profiler_mongoc_insert_platform(int *cid, const char *name, float *lon, float *lat, float *z) {
  if (*cid >= nbundle) {
    return FORTRAN_MONGO_MEMORY_ERROR;
  }
  struct MongoObjectBundle *bundle = &bundles[*cid];

  bson_t *doc;
  bson_error_t error;

  doc = BCON_NEW(
    "sid", BCON_UTF8(name),
    "location", "{",
      "type", "Point",
      "coordinates", "[", BCON_DOUBLE(*lon), BCON_DOUBLE(*lat), "]",
    "}",
    "z", BCON_DOUBLE(*z)
  );

  if (!mongoc_collection_insert_one(bundle->col, doc, NULL, NULL, &error)) {
    bson_destroy(doc);
    if (error.code == MONGOC_ERROR_DUPLICATE_KEY) {
      return FORTRAN_MONGO_INSERT_DUP_WARN;
    } else {
      printf("%s\n", name);
      printf("[Error]: profiler_mongoc_insert_platform: %s\n", error.message);
      return FORTRAN_MONGO_INSERT_ERROR;
    }
  }

  bson_destroy(doc);

  return FORTRAN_MONGO_NO_ERROR;
}

int profiler_mongoc_insert_record(int *cid, const char *name, double *timestamp, int *nlev, float **h, float **ua, float **va) {
  if (*cid >= nbundle) {
    return FORTRAN_MONGO_MEMORY_ERROR;
  }
  struct MongoObjectBundle *bundle = &bundles[*cid];

  bson_t *doc;
  bson_error_t error;
 
  doc = BCON_NEW(
    "sid"   , BCON_UTF8(name),
    "time"  , BCON_DATE_TIME(*timestamp * 1000) // UTC time
  );
  bson_t child;
  char key[3];
  if (*nlev > 0) {
    // ---------------------------------------------------------------------------
    //                                      h
    bson_init(&child);
    bson_append_array_begin(doc, "h", -1, &child);
    for (int k = 0; k < *nlev; ++k) {
      sprintf(key, "%d", k);
      BSON_APPEND_DOUBLE(&child, key, (*h)[k]);
    }
    bson_append_array_end(doc, &child);
    // ---------------------------------------------------------------------------
    //                                     ua
    bson_init(&child);
    bson_append_array_begin(doc, "ua", -1, &child);
    for (int k = 0; k < *nlev; ++k) {
      sprintf(key, "%d", k);
      BSON_APPEND_DOUBLE(&child, key, (*ua)[k]);
    }
    bson_append_array_end(doc, &child);
    // ---------------------------------------------------------------------------
    //                                     va
    bson_init(&child);
    bson_append_array_begin(doc, "va", -1, &child);
    for (int k = 0; k < *nlev; ++k) {
      sprintf(key, "%d", k);
      BSON_APPEND_DOUBLE(&child, key, (*va)[k]);
    }
    bson_append_array_end(doc, &child);
  }

  if (!mongoc_collection_insert_one(bundle->col, doc, NULL, NULL, &error)) {
    bson_destroy(doc);
    if (error.code == MONGOC_ERROR_DUPLICATE_KEY) {
      return FORTRAN_MONGO_INSERT_DUP_WARN;
    } else {
      printf("%s\n", name);
      printf("[Error]: profiler_mongoc_insert_record: %s\n", error.message);
      return FORTRAN_MONGO_INSERT_ERROR;
    }
  }

  bson_destroy(doc);

  return FORTRAN_MONGO_NO_ERROR;

}
